<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>优化写法</title>
    <style>
        *,
        *::after,
        *::before {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        :root {
            min-height: 100vh;
        }

        :root:focus-within {
            scroll-behavior: smooth;
        }

        body {
            min-height: inherit;
        }
    </style>
</head>

<body>
</body>
<script>
    "use strict"; {
        // 1.隐式转换
        let res1 = "3" + 4 + 5; //345
        let res2 = 3 + 4 + "5"; //75

    }; {
        // 2.使用 var 声明变量, 但是 var 存在一些作用域问题，容易造成变量污染等问题
        function example() {
            var foo = "bar";
            if (true) {
                var foo = "baz";
                console.log(foo); // 'baz'
            }
            console.log(foo); // 'baz'
        };
    }; {
        // 3.频繁操作 DOM
        // 不推荐
        document.getElementById('my-button')?.addEventListener('click', function () {
            document.getElementById('my-text').innerText = 'Hello, world!';
        });

        // 推荐
        const myText = document.getElementById('my-text');
        document.getElementById('my-button')?.addEventListener('click', function () {
            if (myText) {
                myText.innerText = 'Hello, world!';
            }
        });
    }; {
        // 5.使用全局变量
        // 不推荐
        function foo() {
            globalVar = "bar";
        }

        // 推荐
        const myModule = (function () {
            const localVar = "baz";

            function foo() {
                // do something with localVar
            }

            return {
                foo: foo
            };
        })();
    }; {
        // 6. 忽略分号 JavaScript 允许在语句结尾省略分号，
        // 但这往往会导致一些错误，特别是当代码压缩或合并时。因此，建议始终在语句结尾加上分号，以避免潜在的问题

        // 不推荐
        let x = 1
        let y = 2

        // 推荐
        let x1 = 1;
        let y2 = 2;
    }; {
        Object.prototype.ha = "女";

        // 7. 使用 for-in 循环
        const person = {
            name: "Alice",
            age: 30,
            gender: "female"
        };

        // 不推荐
        for (const key in person) {
            console.log(`person ==`, person[key]);
        };

        // 推荐
        console.log(Object.keys(person));
        Object.keys(person).forEach(key => console.log(person[key]));
    }; {
        // 9. 使用 eval()

        // 不推荐
        eval("console.log('Hello, world!')");

        // 推荐 微信小程序中会禁止这种写法的
        const code = "console.log('Hello, world!')";
        Function(code)();
    }; {
        // 10. 忽略错误处理

        try {
            // some code
        } catch (e) { }

        // 尽管这个抛出异常的代码可能无关紧要，但是如果没有正确处理异常，就可能在开发或运行时期间导致问题。
        // 为了避免这个问题，我们应该始终正确处理异常，例如通过日志记录或显示用户友好的错误信息。
    }; {
        // 11. 将函数作为参数传递时忘记绑定 this

        // 将函数作为参数传递时，需要注意绑定 this 的值。例如：
        const obj = {
            name: 'Alice',
            greet: function () {
                console.log('Hello, ' + this.name);
            }
        };
        setTimeout(obj.greet, 1000); // Hello, undefined
        // 正确的写法应该是使用 bind 方法：



        const obj1 = {
            name: 'Alice',
            greet: function () {
                console.log('Hello, ' + this.name);
            }
        };
        setTimeout(obj1.greet.bind(obj1), 1000); // Hello, Alice
    }
</script>

</html>